/*
 * SipMessage.h
 *
 *  Created on: Dec 6, 2011
 *      Author: shaohong
 */

#ifndef SIPMESSAGE_H_
#define SIPMESSAGE_H_

#include <string>
#include <map>

using namespace std;

namespace nmps {

enum Transport{ UDP, TCP};

class Hop {
public:
	Hop(string ip, int port, Transport transport);
	virtual ~Hop();

	string ip;
	int port;
	Transport transport;
};

class SipDialog;
class SipResponse;
class SipRequest;
class SipServer;

class SipMessage {
public:
	SipMessage();
	virtual ~SipMessage();

	// return the content of this sip message
	string getContent();

	// return the call-id of this sip message
	string getCallID();

	// add the given header to the message
	void addHeader(string headerName, string headerValue);

	// given a header name, return the headerValue
	string getHeader(string headerName);

	string getContentType();

	void setContentType(string contentType);


	void setContent(string contentType, string contentStr);

	// whether this message is a request message
	virtual bool isRequest() = 0;

	// whether this message is a response message
	virtual bool isResponse() = 0;

	virtual string toString() = 0;

	// return the nextHop that this message should sent to
	virtual Hop * getTargetAddr() = 0;

	// get the SipDialog associated with this SipMessage
	SipDialog * getDialog();

	void setSipDialog(SipDialog * sipDialog);
	/**
	 * Parse the given received message into a SipMessage
	 */
	static SipMessage * parseSipMessage(string receiveMessage);

	static bool hasTag(string& uriAndParams);
	static void addTag(string& uriAndParams);

	//create an Answer SDP based on the offerSDP
	static string createAnswerSDP(string &offerSDP);

	static string intoToString(int i);
	static int stringToInt(string intStr);
	static string extractRtpIP(string& offerSDP);
	static int extractRtpPort(string& offerSDP);

protected:
	string content;

	//The sip headers
	map<string, string> headers;

	SipDialog * dialog;
};

class SipRequest: public SipMessage {
public:
	SipRequest();
	virtual ~SipRequest();

	string getMethod(); // return the method in this request

	string getRequestUri();

	void setMethod(string methodName);

	void setRequestURI(string requestURI);

	bool isRequest();

	bool isResponse();

	Hop * getTargetAddr();

	//serialize this SIP response;
	string toString();

	/**
	 * create an response based on the current request
	 */
	SipResponse * createResponse(int statusCode, string reasonPhrase);

private:
	string method;
	string requestUri;
};

class SipResponse: public SipMessage {
public:
	SipResponse();
	virtual ~SipResponse();

	int getStatusCode();

	void setStatusCode(int statusCode);

	void setReasonPhrase(string reasonPhrase);

	string getReasonPhrase();

	bool isRequest();

	bool isResponse();

	static bool isFinal(int statusCode);

	Hop * getTargetAddr();

//	// return the request associated with this response
//	SipRequest * getRequest();
//
//	void setRequest(SipRequest * request);

	//serialize this SIP response;
	string toString();

private:
	int statusCode;
	string reasonPhrase;
//	SipRequest * request;

};

} /* namespace nmps */
#endif /* SIPMESSAGE_H_ */
